package org.vectrics.user.web.struts;

import java.util.Collection;
import java.util.Iterator;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.vectrics.common.http.HttpUtils;
import org.vectrics.common.util.StringUtils;
import org.vectrics.domain.Domain;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.VectricsActionData;
import org.vectrics.user.Person;
import org.vectrics.user.UserPrivilege;
import org.vectrics.user.UserPrivilegeType;

public class UserPrivilegesHelper {
    private transient final Logger log = Logger.getLogger(this.getClass());

    public UserPrivilegesHelper() {
        super();
    }

    public String getSelectParameterName(UserPrivilegeType userPrivilegeType) {
        String result = "";
        result += "priv_";
        result += userPrivilegeType.getCode();
        return (result);
    }

    public String getHiddenParameterName(UserPrivilegeType userPrivilegeType) {
        String result = "ent_";
        result += "priv_";
        result += userPrivilegeType.getCode();
        return (result);
    }

    // Save the user roles and group memberships.
    public void saveRoles(VectricsActionData actionData, Person person, Domain domain, boolean global) {
        HttpUtils.logRequestInfo(actionData.getRequest(), log, Level.INFO);

        // Show person roles before save.
        String message = "Before save, person=" + person.getName();
        Iterator personRoleIter = person.getPrivileges().iterator();
        while (personRoleIter.hasNext()) {
            UserPrivilege userPrivilege = (UserPrivilege) personRoleIter.next();
            String doStr = "null";
            if (userPrivilege.getDomain() != null)
                doStr = userPrivilege.getDomain().getDescription();
            message += "\r\n - Role:" + userPrivilege.getPrivilegeType().getCode() + "  Global:"
                    + userPrivilege.getGlobal() + "  Domain:" + doStr;
        }
        log.debug(message);

        Iterator roleIter = CoreServiceLocator.getPersonService().findAllUserPrivilegeTypes().iterator();
        while (roleIter.hasNext()) {
            UserPrivilegeType roleType = (UserPrivilegeType) roleIter.next();
            saveRole(actionData, roleType, person, domain);
        }
        CoreServiceLocator.getPersonService().updatePerson(person);
    }

    private void saveRole(VectricsActionData actionData, UserPrivilegeType roleType, Person person, Domain domain) {
        boolean requestHasPriv = requestHasRoleParam(actionData, roleType);
        if (requestHasPriv) {
            String userSelectedValue = this.userSelectedPrivValue(actionData, roleType);
            if (StringUtils.isNullOrBlank(userSelectedValue)) {
                log.debug("No param for role, ignoring and assuming no entry required for param");
            } else {
                log.debug("Request has entry.  Priv: " + roleType.getCode() + "  User Selected: " + userSelectedValue);

                UserPrivilege previoususerPrivilege = person.findPrivilege(roleType, domain);
                log.debug("Role: " + roleType.getCode() + "  Selected role: " + userSelectedValue);

                if ((previoususerPrivilege == null) && (userSelectedValue.equals("none") == false)) {
                    log.debug("Adding role for user, user did not have role before this save. Role="
                            + roleType.getCode());
                    if (userSelectedValue.equals("domain")) {
                        person.addPrivilege(roleType, domain, false);
                    } else if (userSelectedValue.equals("global")) {
                        person.addPrivilege(roleType, domain, true);
                    }
                } else if ((previoususerPrivilege != null) && (userSelectedValue.equals("none"))) {
                    log.debug("Removing role from person.  Role=" + roleType.getCode());
                    person.removePrivilege(roleType, domain);
                } else if ((previoususerPrivilege != null) && (previoususerPrivilege.getGlobal() == true)
                        && (userSelectedValue.equals("domain"))) {
                    log.debug("Role is same for user.  Role=" + roleType.getCode());
                    previoususerPrivilege.setGlobal(false);
                } else if ((previoususerPrivilege != null) && (previoususerPrivilege.getGlobal() == false)
                        && (userSelectedValue.equals("global"))) {
                    log.debug("Role is same for user.  Role=" + roleType.getCode());
                    previoususerPrivilege.setGlobal(true);
                } else {

                }
            }
        } else {
            log.debug("Request does not allow entry of priv.  Priv: " + roleType.getCode());
        }
    }

    private String userSelectedPrivValue(VectricsActionData actionData, UserPrivilegeType roleType) {
        String paramName = this.getSelectParameterName(roleType);
        String paramValue = actionData.getRequest().getParameter(paramName);
        return (paramValue);
    }

    private boolean requestHasRoleParam(VectricsActionData actionData, UserPrivilegeType roleType) {
        boolean result = false;
        String paramName = this.getHiddenParameterName(roleType);
        String paramValue = actionData.getRequest().getParameter(paramName);
        if ((paramValue != null) && (paramValue.length() > 0)) {
            result = true;
        }
        return (result);
    }

    private UserPrivilege findRole(UserPrivilegeType roleType, Domain domain, Collection personRoles) {
        UserPrivilege found = null;
        Iterator iter = personRoles.iterator();
        while ((found == null) && (iter.hasNext())) {
            UserPrivilege userPrivilege = (UserPrivilege) iter.next();
            if ((roleType.getCode().equals(userPrivilege.getPrivilegeType().getCode()))
                    && (userPrivilege.getDomain() != null)
                    && (userPrivilege.getDomain().getId().equals(domain.getId()))) {
                found = userPrivilege;
            }
        }
        return (found);
    }

}
